package com.yonyou.openapi.selfbuilddemo;

import com.yonyou.openapi.common.cryptor.OpenApiRequestEncrypt;
import com.yonyou.openapi.common.exception.BusinessException;
import com.yonyou.openapi.pojo.GatewayAddressResponse;
import com.yonyou.openapi.pojo.OpenApiResponse;
import com.yonyou.openapi.util.RequestUtil;
import com.yonyou.openapi.util.UrlUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 功能描述: 自建应用模式调用示例
 * @Author: jiaoguojin
 * @Date: 2024/1/3 16:23
 */
@SpringBootTest
@Slf4j
class SelfBuildDemo {

    //使用您当前租户的租户id
	private final static String TENANT_ID = "XXXXXXXX";

	//企业自建获取token地址
	private static final String URL_SELF_BUILD_ACCESS_TOKEN = "/open-auth/selfAppAuth/base/v1/getAccessToken";

	//第一个税务云接口，开票点档案-查询
	private static final String ORGUNIT_QUERYTREE = "/yonbip/tax/yonbip-fi-taxbd/bd/api/station/query";

	@Value("${open-api.gateway-address-url}")
	String gatewayAddressUrl;

	@Value("${open-api.app-key}")
	String appKey;

	@Value("${open-api.app-secret}")
	String appSecret;

	/**
	 * 功能描述: 获取对应租户接口的域名信息（建议放到配置文件，或者缓存里，禁止每次调用接口都获取一次。一般不会变，租户迁移或者大调整可能会变）
	 * @Author: jiaoguojin
	 * @Date: 2024/1/3 16:05
	 */
	@Test
	public void getDomain() throws IOException {
		String addressUrl = gatewayAddressUrl.replace("%s",TENANT_ID);
		GatewayAddressResponse gatewayAddressResponse = RequestUtil.doGetType(addressUrl,GatewayAddressResponse.class);
		log.info("调用业务接口地址："+gatewayAddressResponse.getData().getGatewayUrl());
		log.info("获取token接口地址："+gatewayAddressResponse.getData().getTokenUrl());
	}

	/**
	 * 功能描述: 获取token示例代码（建议放到缓存里，有效期两个小时，最后的半小时为token刷新窗口期，也就是一个半小时后可获取到新的token，完成续期。禁止每次调用接口都获取一次）
	 * @Author: jiaoguojin
	 * @Date: 2024/1/3 16:05
	 */
	@Test
	public void getToken() throws IOException {

		//getDomain()返回的tokenUrl
		String tokenDomain = "https://dbox.yonyoucloud.com/iuap-api-auth";

		Map<String, String> params = new HashMap<>();
		//params.put("tenantId", TENANT_ID);企业自建不需要传租户id
		params.put("appKey", appKey);
		params.put("timestamp", String.valueOf(System.currentTimeMillis()));
		String signature = OpenApiRequestEncrypt.signature(params, appSecret);
		params.put("signature", signature);
		String tokenUrl = UrlUtil.concatURL(tokenDomain, URL_SELF_BUILD_ACCESS_TOKEN, "?", UrlUtil.buildQueryString(params, false));
		log.info("获取token请求地址为:"+ tokenUrl);

		OpenApiResponse body = RequestUtil.doGet(tokenUrl,null,OpenApiResponse.class);
		if (body == null) {
			throw new BusinessException("unexpected response null when request open api isv access token");
		}
		body.check();
		log.info("获取token结果为:"+ body.getData());
	}

	/**
	 * 功能描述: 调用业务接口示例 开票点档案-查询接口
	 * @Author: jiaoguojin
	 * @Date: 2024/1/4 10:14
	 */
	@Test
	public void testDemo() throws IOException {

		//getDomain()返回的tokenUrl
		String gatewayUrl = "https://dbox.yonyoucloud.com/iuap-api-gateway";

		//getToken()返回的token
		String token = "YT5_TGYonBip-commldev-1-serviceTG_MC0CFDSHBkr0h4/fLRtTddg6I8Vpv9juAhUAkAXCp9PxnrcedRtNwRiJml+/TbA=_CHJ5YmVudGM1kII4jZXgKEAIn0edrN5NeQgACeiUoeWuh+eEtgAAAAAAAAAAAAAAAMjOro1ikAEAAAAAAAAAxCJ0gGbEMqF/Zg1pdWFwLXV1YXMtY2FzAACQUexRS6p+Qj66tIAYkCsJwgdkY2NvcmUwAAA=";

		Map<String, String> tokenParam = new HashMap<>();
		tokenParam.put("access_token",  URLEncoder.encode(token, StandardCharsets.UTF_8.name()));//token要url编码处理，否则有特殊字符的时候会报非法token
		String url = UrlUtil.concatURL(gatewayUrl, ORGUNIT_QUERYTREE, "?", UrlUtil.buildQueryString(tokenParam, false));
		log.info("接口请求地址为:"+ url);

		Map<String, Object> params = new HashMap<>();
		params.put("pageSize",10);
		params.put("pageNum",1);
		OpenApiResponse body = RequestUtil.doPost(url,params,OpenApiResponse.class);
		if (body == null) {
			throw new BusinessException("unexpected response null when request open api isv access token");
		}
		body.check();
		log.info("返回结果为:"+ body.getData());
	}

}
